/*!
 * \file ParserAdapter.cpp
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief 行情解析器适配器实现文件
 * 
 * \details 本文件实现了WonderTrader数据服务系统的行情解析器适配器类ParserAdapter：
 *          - 实现行情解析器接口的适配和管理
 *          - 处理行情数据的接收、解析和分发
 *          - 支持动态加载行情解析器模块
 *          - 提供合约过滤和交易所过滤功能
 *          - 实现行情数据的实时推送和存储
 *          - 管理行情解析器的生命周期
 *          - 提供日志记录和错误处理机制
 */
#include "ParserAdapter.h"
#include "DataManager.h"
#include "StateMonitor.h"
#include "WtHelper.h"

#include "../Share/StrUtil.hpp"
#include "../Share/DLLHelper.hpp"

#include "../Includes/WTSVariant.hpp"
#include "../Includes/WTSContractInfo.hpp"
#include "../Includes/WTSDataDef.hpp"
#include "../Includes/WTSVariant.hpp"

#include "../WTSTools/WTSBaseDataMgr.h"
#include "../WTSTools/WTSLogger.h"


//////////////////////////////////////////////////////////////////////////
//ParserAdapter
/**
 * @brief 构造函数
 * @details 初始化行情解析器适配器
 * @param bgMgr 基础数据管理器
 * @param dtMgr 数据管理器
 */
ParserAdapter::ParserAdapter(WTSBaseDataMgr * bgMgr, DataManager* dtMgr)
	: _parser_api(NULL)
	, _remover(NULL)
	, _stopped(false)
	, _bd_mgr(bgMgr)
	, _dt_mgr(dtMgr)
	, _cfg(NULL)
{
}

/**
 * @brief 析构函数
 * @details 清理行情解析器适配器资源
 */
ParserAdapter::~ParserAdapter()
{
}

/**
 * @brief 外部初始化接口
 * @details 使用外部提供的解析器API进行初始化
 * @param id 解析器标识
 * @param api 解析器API接口
 * @return bool 初始化是否成功
 */
bool ParserAdapter::initExt(const char* id, IParserApi* api)
{
	if (api == NULL)
		return false;

	_parser_api = api;
	_id = id;

	if (_parser_api)
	{
		// 注册回调接口
		_parser_api->registerSpi(this);

		// 初始化解析器
		if (_parser_api->init(NULL))
		{
			// 订阅所有合约
			ContractSet contractSet;
			WTSArray* ayContract = _bd_mgr->getContracts();
			WTSArray::Iterator it = ayContract->begin();
			for (; it != ayContract->end(); it++)
			{
				WTSContractInfo* contract = STATIC_CONVERT(*it, WTSContractInfo*);
				contractSet.insert(contract->getFullCode());
			}

			ayContract->release();

			_parser_api->subscribe(contractSet);
			contractSet.clear();
		}
		else
		{
			WTSLogger::log_dyn("parser", _id.c_str(), LL_ERROR, "[%s] Parser initializing failed: api initializing failed...", _id.c_str());
		}
	}

	return true;
}

/**
 * @brief 初始化解析器适配器
 * @details 根据配置参数初始化解析器适配器，加载解析器模块
 * @param id 解析器标识
 * @param cfg 配置参数
 * @return bool 初始化是否成功
 */
bool ParserAdapter::init(const char* id, WTSVariant* cfg)
{
	if (cfg == NULL)
		return false;

	_id = id;

	if (_cfg != NULL)
		return false;

	_cfg = cfg;
	_cfg->retain();

	{
		// 加载模块
		if (cfg->getString("module").empty())
			return false;

		std::string module = DLLHelper::wrap_module(cfg->getCString("module"), "lib");;

		// 检查模块文件是否存在
		if (!StdFile::exists(module.c_str()))
		{
			module = WtHelper::get_module_dir();
			module += "parsers/";
			module += DLLHelper::wrap_module(cfg->getCString("module"), "lib");
		}

		// 加载动态库
		DllHandle hInst = DLLHelper::load_library(module.c_str());
		if (hInst == NULL)
		{
			WTSLogger::log_dyn("parser", _id.c_str(), LL_ERROR, "[%s] Parser module %s loading failed", _id.c_str(), module.c_str());
			return false;
		}
		else
		{
			WTSLogger::log_dyn("parser", _id.c_str(), LL_INFO, "[%s] Parser module %s loaded", _id.c_str(), module.c_str());
		}

		// 获取创建解析器的函数
		FuncCreateParser pFuncCreateParser = (FuncCreateParser)DLLHelper::get_symbol(hInst, "createParser");
		if (NULL == pFuncCreateParser)
		{
			WTSLogger::log_dyn("parser", _id.c_str(), LL_FATAL, "[%s] Entrance function createParser not found", _id.c_str());
			return false;
		}

		// 创建解析器实例
		_parser_api = pFuncCreateParser();
		if (NULL == _parser_api)
		{
			WTSLogger::log_dyn("parser", _id.c_str(), LL_FATAL, "[%s] Creating parser api failed", _id.c_str());
			return false;
		}

		// 获取删除解析器的函数
		_remover = (FuncDeleteParser)DLLHelper::get_symbol(hInst, "deleteParser");
	}

	// 处理交易所过滤器配置
	const std::string& strFilter = cfg->getString("filter");
	if (!strFilter.empty())
	{
		const StringVector &ayFilter = StrUtil::split(strFilter, ",");
		auto it = ayFilter.begin();
		for (; it != ayFilter.end(); it++)
		{
			_exchg_filter.insert(*it);
		}
	}

	// 处理合约代码过滤器配置
	std::string strCodes = cfg->getString("code");
	if (!strCodes.empty())
	{
		const StringVector &ayCodes = StrUtil::split(strCodes, ",");
		auto it = ayCodes.begin();
		for (; it != ayCodes.end(); it++)
		{
			_code_filter.insert(*it);
		}
	}

	if (_parser_api)
	{
		// 注册回调接口
		_parser_api->registerSpi(this);

		// 初始化解析器
		if (_parser_api->init(cfg))
		{
			ContractSet contractSet;
			if (!_code_filter.empty())//如果有指定合约过滤器
			{
				ExchgFilter::iterator it = _code_filter.begin();
				for (; it != _code_filter.end(); it++)
				{
					//全代码,格式如SSE.600000,期货格式为CFFEX.IF2005
					std::string code, exchg;
					auto ay = StrUtil::split((*it).c_str(), ".");
					if (ay.size() == 1)
						code = ay[0];
					else
					{
						exchg = ay[0];
						code = ay[1];
					}
					WTSContractInfo* contract = _bd_mgr->getContract(code.c_str(), exchg.c_str());
					contractSet.insert(contract->getFullCode());
				}
			}
			else if (!_exchg_filter.empty())
			{
				// 按交易所过滤
				ExchgFilter::iterator it = _exchg_filter.begin();
				for (; it != _exchg_filter.end(); it++)
				{
					WTSArray* ayContract = _bd_mgr->getContracts((*it).c_str());
					WTSArray::Iterator it = ayContract->begin();
					for (; it != ayContract->end(); it++)
					{
						WTSContractInfo* contract = STATIC_CONVERT(*it, WTSContractInfo*);
						contractSet.insert(contract->getFullCode());
					}

					ayContract->release();
				}
			}
			else
			{
				// 订阅所有合约
				WTSArray* ayContract = _bd_mgr->getContracts();
				WTSArray::Iterator it = ayContract->begin();
				for (; it != ayContract->end(); it++)
				{
					WTSContractInfo* contract = STATIC_CONVERT(*it, WTSContractInfo*);
					contractSet.insert(contract->getFullCode());
				}

				ayContract->release();
			}

			// 执行订阅
			_parser_api->subscribe(contractSet);
			contractSet.clear();
		}
		else
		{
			WTSLogger::log_dyn("parser", _id.c_str(), LL_ERROR, "[%s] Parser initializing failed: api initializing failed...", _id.c_str());
		}
	}
	else
	{
		WTSLogger::log_dyn("parser", _id.c_str(), LL_ERROR, "[%s] Parser initializing failed: creating api failed...", _id.c_str());
	}

	return true;
}

/**
 * @brief 释放解析器适配器
 * @details 释放解析器适配器资源，停止解析器运行
 */
void ParserAdapter::release()
{
	_stopped = true;
	if (_parser_api)
	{
		_parser_api->release();
	}

	// 删除解析器实例
	if (_remover)
		_remover(_parser_api);
	else
		delete _parser_api;
}

/**
 * @brief 运行解析器
 * @details 启动解析器连接，开始接收行情数据
 * @return bool 运行是否成功
 */
bool ParserAdapter::run()
{
	if (_parser_api == NULL)
		return false;

	_parser_api->connect();
	return true;
}

/**
 * @brief 处理合约列表
 * @details 处理解析器推送的合约列表信息
 * @param aySymbols 合约列表
 */
void ParserAdapter::handleSymbolList( const WTSArray* aySymbols )
{
	
}

/**
 * @brief 处理逐笔成交数据
 * @details 处理解析器推送的逐笔成交数据
 * @param transData 逐笔成交数据
 */
void ParserAdapter::handleTransaction(WTSTransData* transData)
{
	if (_stopped)
		return;

	// 检查数据有效性
	if (transData->actiondate() == 0 || transData->tradingdate() == 0)
		return;

	// 验证合约信息
	WTSContractInfo* contract = _bd_mgr->getContract(transData->code(), transData->exchg());
	if (contract == NULL)
		return;

	// 写入逐笔成交数据
	_dt_mgr->writeTransaction(transData);
}

/**
 * @brief 处理订单明细数据
 * @details 处理解析器推送的Level2订单明细数据
 * @param ordDetailData 订单明细数据
 */
void ParserAdapter::handleOrderDetail(WTSOrdDtlData* ordDetailData)
{
	if (_stopped)
		return;

	// 检查数据有效性
	if (ordDetailData->actiondate() == 0 || ordDetailData->tradingdate() == 0)
		return;

	// 验证合约信息
	WTSContractInfo* contract = _bd_mgr->getContract(ordDetailData->code(), ordDetailData->exchg());
	if (contract == NULL)
		return;

	// 写入订单明细数据
	_dt_mgr->writeOrderDetail(ordDetailData);
}

/**
 * @brief 处理订单队列数据
 * @details 处理解析器推送的Level2订单队列数据
 * @param ordQueData 订单队列数据
 */
void ParserAdapter::handleOrderQueue(WTSOrdQueData* ordQueData)
{
	if (_stopped)
		return;

	// 检查数据有效性
	if (ordQueData->actiondate() == 0 || ordQueData->tradingdate() == 0)
		return;

	// 验证合约信息
	WTSContractInfo* contract = _bd_mgr->getContract(ordQueData->code(), ordQueData->exchg());
	if (contract == NULL)
		return;
		
	// 写入订单队列数据
	_dt_mgr->writeOrderQueue(ordQueData);
}

/**
 * @brief 处理tick行情数据
 * @details 处理解析器推送的tick行情数据
 * @param quote tick数据
 * @param procFlag 处理标志
 */
void ParserAdapter::handleQuote( WTSTickData *quote, uint32_t procFlag )
{
	if (_stopped)
		return;

	// 检查数据有效性
	if (quote->actiondate() == 0 || quote->tradingdate() == 0)
		return;

	// 获取或设置合约信息
	WTSContractInfo* contract = quote->getContractInfo();
	if (contract == NULL)
	{
		contract = _bd_mgr->getContract(quote->code(), quote->exchg());
		quote->setContractInfo(contract);
	}

	if (contract == NULL)
		return;

	// 写入tick数据
	if (!_dt_mgr->writeTick(quote, procFlag))
		return;
}

/**
 * @brief 处理解析器日志
 * @details 处理解析器产生的日志信息
 * @param ll 日志级别
 * @param message 日志消息
 */
void ParserAdapter::handleParserLog( WTSLogLevel ll, const char* message)
{
	if (_stopped)
		return;

	WTSLogger::log_raw_by_cat("parser", ll, message);
}

/**
 * @brief 获取基础数据管理器
 * @details 返回基础数据管理器接口
 * @return IBaseDataMgr* 基础数据管理器指针
 */
IBaseDataMgr* ParserAdapter::getBaseDataMgr()
{
	return _bd_mgr;
}


//////////////////////////////////////////////////////////////////////////
//ParserAdapterMgr
/**
 * @brief 释放解析器适配器管理器
 * @details 释放所有解析器适配器资源
 */
void ParserAdapterMgr::release()
{
	for (auto it = _adapters.begin(); it != _adapters.end(); it++)
	{
		it->second->release();
	}

	_adapters.clear();
}

/**
 * @brief 添加解析器适配器
 * @details 向管理器中添加一个解析器适配器
 * @param id 适配器标识
 * @param adapter 适配器对象
 * @return bool 添加是否成功
 */
bool ParserAdapterMgr::addAdapter(const char* id, ParserAdapterPtr& adapter)
{
	if (adapter == NULL || strlen(id) == 0)
		return false;

	auto it = _adapters.find(id);
	if (it != _adapters.end())
	{
		WTSLogger::error(" Same name of parsers: %s", id);
		return false;
	}

	_adapters[id] = adapter;

	return true;
}

ParserAdapterPtr ParserAdapterMgr::getAdapter(const char* id)
{
	auto it = _adapters.find(id);
	if (it != _adapters.end())
	{
		return it->second;
	}

	return ParserAdapterPtr();
}

void ParserAdapterMgr::run()
{
	for (auto it = _adapters.begin(); it != _adapters.end(); it++)
	{
		it->second->run();
	}

	WTSLogger::info("%u parsers started", _adapters.size());
}